Android  LayoutInflater.inflate()상세 설명 및 분석

Android  LayoutInflater.inflate()상세 설명
LayoutInflater.inflate()깊이 이해
우 리 는 공식 화 된 프 리 셋 코드 에 익숙 하기 때문에 우아 한 디 테 일 을 무시 하기 도 한다.Layout Inflater 와 Fragment 의 onCreate View()에 View 를 채 우 는 방식 이 저 에 게 이런 느낌 을 주 었 습 니 다.이 종 류 는 XML 파일 을 대응 하 는 ViewGroup 과 컨트롤 Widget 으로 변환 하 는 데 사 용 됩 니 다.나 는 구 글 의 공식 문서 와 인터넷 상의 다른 토론 에서 관련 설명 을 찾 아 보 았 으 나,많은 사람들 이 Layout Inflater 의 inflate()방법의 세부 사항 을 잘 모 를 뿐만 아니 라,심지 어 는 그것 을 오용 하고 있 음 을 발견 하 였 다.
Google 에서 attachToRoot(즉 inflate()방법의 세 번 째 인자)에 관 한 문서 가 너무 모호 하기 때 문 입 니 다.
채 워 진 층 은 루트 매개 변수 내부 에 붙 여야 합 니까?false 라면 루트 인 자 는 XML 루트 요소 View 에 올 바른 LayoutParams 의 하위 클래스 를 만 드 는 데 만 적 용 됩 니 다.
사실은 attachToRoot 가 true 라면 첫 번 째 매개 변수의 layot 파일 은 두 번 째 매개 변수 가 지정 한 ViewGroup 에 채 워 지고 추 가 됩 니 다.방법 은 결 합 된 View 를 되 돌려 줍 니 다.루트 요 소 는 두 번 째 매개 변수 View Group 입 니 다.false 라면 첫 번 째 매개 변수 가 지정 한 layot 파일 이 채 워 져 View 로 돌아 갑 니 다.이 View 의 루트 요 소 는 layot 파일 의 루트 요소 입 니 다.true 든 false 든 View Group 의 LayoutParams 가 layot 파일 에 발생 하 는 View 대상 을 정확하게 측정 하고 배치 해 야 합 니 다.
attach ToRoot 에서 true 대표 layot 파일 로 채 워 진 View 는 ViewGroup 에 직접 추가 되 고 false 에 들 어가 면 만 든 View 는 다른 방식 으로 ViewGroup 에 추 가 됩 니 다.
우 리 는 두 가지 상황 에 대해 예 를 들 어 더욱 깊이 이해 합 시다.
attachToRoot 는 True 입 니 다.
만약 에 저희 가 XML layot 파일 에 Button 을 쓰 고 너비 와 높이 를 match 로 지정 했다 고 가정 합 니 다.parent。

<Button xmlns:android="http://schemas.android.com/apk/res/android"
  android:layout_width="match_parent"
  android:layout_height="match_parent"
  android:id="@+id/custom_button">
</Button>
지금 우 리 는 이 단 추 를 Fragment 나 Activity 의 LinearLayout 에 동적 으로 추가 하고 싶 습 니 다.만약 에 여기 LinearLayout 가 구성원 변수 인 mLinearLayout 이 라면 우 리 는 다음 과 같은 코드 를 통 해 목 표를 달성 해 야 합 니 다.

inflater.inflate(R.layout.custom_button, mLinearLayout, true);
button 을 채 울 layot 자원 파일 을 지정 한 다음 Layout Inflater 에 button 을 mLinearLayout 에 추가 하고 싶다 고 알려 줍 니 다.여기 Button 의 LayoutParams 종 류 는 LinearLayout.LayoutParams 입 니 다.
아래 코드 도 같은 효과 가 있 습 니 다.LayoutInflater 의 두 매개 변수의 inflate()방법 은 attachToRoot 를 true 로 자동 으로 설정 합 니 다.

inflater.inflate(R.layout.custom_button, mLinearLayout);
다른 하 나 는 attachToRoot 에서 true 를 전달 하 는 경우 사용자 정의 View 를 사용 합 니 다.레이아웃 파일 의 루트 요소 에 탭 이 있 는 예 를 봅 니 다.레이 블 은 이 layot 파일 의 루트 뷰 그룹 을 표시 합 니 다.여러 종류 가 있 을 수 있 습 니 다.

public class MyCustomView extends LinearLayout {
  ...
  private void init() {
  LayoutInflater inflater = LayoutInflater.from(getContext());
  inflater.inflate(R.layout.view_with_merge_tag, this);
  }
}
이것 이 바로 attachToRoot 를 잘 사용 하 는 예 이다.이 예 에서 layot 파일 은 View Group 을 루트 요소 로 하지 않 았 기 때문에 사용자 정의 LinearLayout 를 루트 요소 로 지정 합 니 다.layot 파일 에 FrameLayout 가 아 닌 루트 요소 가 있다 면 FrameLayout 와 그 하위 요 소 는 정상적으로 채 울 수 있 고 그 다음 에 LinearLayout 에 추 가 됩 니 다.LinearLayout 는 루트 View Group 으로 FrameLayout 와 그 하위 요 소 를 포함 합 니 다.
attachToRoot 는 False 입 니 다.
언제 attach ToRoot 가 false 인지 봅 시다.이 경우 inflate()방법의 첫 번 째 매개 변수 가 지정 한 View 는 두 번 째 매개 변수 가 지정 한 View Group 에 추가 되 지 않 습 니 다.
방금 예 시 된 Button 을 기억 해 보 세 요.layot 파일 을 통 해 사용자 정의 Button 을 mLinearLayout 에 추가 하고 싶 습 니 다.attachToRoot 가 false 일 때,우 리 는 버튼 을 mLinearLayout 에 추가 할 수 있 지만,이것 은 우리 가 직접 해 야 합 니 다.

Button button = (Button) inflater.inflate(R.layout.custom_button, mLinearLayout, false);
mLinearLayout.addView(button);
이 두 줄 의 코드 는 방금 attachToRoot 가 true 였 을 때의 한 줄 의 코드 와 같은 효 과 를 가진다.false 를 통 해 Layout Inflater 에 게 루트 요소 View Group 에 View 를 추가 하고 싶 지 않다 고 알려 줍 니 다.잠시 후에 추가 하 겠 다 는 뜻 입 니 다.이 예 에서 잠시 후에 추가 하 는 것 은 inflate()후에 addView()방법 을 호출 하 는 것 입 니 다.
attachToRoot 를 false 로 설정 한 예 에서 View 를 ViewGroup 에 수 동 으로 추가 해 야 하기 때문에 코드 가 많아 졌 습 니 다.Button 을 LinearLayout 에 추가 하 시 겠 습 니까?아니면 한 줄 코드 로 attachToRoot 를 true 로 직접 설정 하 시 겠 습 니까?다음은 어떤 상황 에서 attach ToRoot 가 false 에 들 어가 야 하 는 지 살 펴 보 겠 습 니 다.
모든 RecyclerView 의 하위 요 소 는 attachToRoot 가 false 로 설 정 된 상태 에서 채 워 야 합 니 다.이 부분 View 는 onCreate View Holder()에 채 워 집 니 다.

public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
  LayoutInflater inflater = LayoutInflater.from(getActivity());
  View view = inflater.inflate(android.R.layout.list_item_recyclerView, parent, false);
  return new ViewHolder(view);
}
RecyclerView 는 서브 뷰 를 언제 보 여줄 지 결정 하 는 일 을 맡 고 있 습 니 다.이 건 저희 가 결정 하지 않 습 니 다.뷰 그룹 에 View 를 추가 하 는 것 은 저희 가 책임 지지 않 는 한 attachToRoot 를 false 로 설정 해 야 합 니 다.
Fragment 의 onCreateView()방법 에 View 를 채 우 고 되 돌 릴 때 attachToRoot 를 false 로 설정 합 니 다.true 에 들 어 오 면 Illegal State Exception 을 던 집 니 다.지정 한 하위 View 에 부모 View 가 있 기 때 문 입 니 다.Fragment 의 View 를 Activity 에 어디 에 넣 을 지 지정 해 야 합 니 다.Fragment 를 추가 하거나 제거 하거나 교체 하 는 것 은 Fragment Manager 의 일 입 니 다.

FragmentManager fragmentManager = getSupportFragmentManager();
Fragment fragment = fragmentManager.findFragmentById(R.id.root_viewGroup);

if (fragment == null) {
  fragment = new MainFragment();
  fragmentManager.beginTransaction().add(R.id.root_viewGroup, fragment).commit();
}

위 코드 중 rootview Group 은 Activity 에서 Fragment 를 설치 하 는 용기 로 inflate()방법의 두 번 째 매개 변수 로 onCreate View()에 전 달 됩 니 다.그것 도 당신 이 inflate()방법 에서 들 어 온 View Group 입 니 다.Fragment Manager 는 Fragment 의 View 를 View Group 에 추가 합 니 다.두 번 추가 하고 싶 지 않 습 니 다.

public View onCreateView(LayoutInflater inflater, ViewGroup parentViewGroup, Bundle savedInstanceState) {
  View view = inflater.inflate(R.layout.fragment_layout, parentViewGroup, false);
  …
  return view;
}
문 제 는 onCreateView()에 View 를 ViewGroup 에 추가 하지 않 아 도 된다 면 왜 ViewGroup 에 들 어 가 려 고 합 니까?왜 inflate()방법 은 루트 View Group 에 전달 되 어야 합 니까?
이 유 는 새로 채 워 진 View 를 View Group 에 바로 추가 할 필요 가 없 기 때 문 입 니 다.이 부모 요소 의 LayoutParams 가 필요 합 니 다.나중에 추가 할 때 View 의 size 와 position 을 결정 합 니 다.
너 는 인터넷 에서 반드시 정확 하지 않 은 건 의 를 만 날 것 이다.어떤 사람들 은 attachToRoot 를 false 로 설정 하면 루트 뷰 그룹 을 null 에 직접 전송 하 라 고 건의 할 것 이다.하지만 부모 요소 가 있다 면 들 어 와 야 합 니 다.

린 트 는 null 을 루트 로 들 어 오지 말 라 고 경고 할 것 이다.당신 의 앱 은 끊 지 않 지만 이상 하 게 보일 수 있 습 니 다.하위 View 에 올 바른 LayoutParams 가 없 을 때 generateDefaultLayoutParams)를 통 해 계산 합 니 다.
기본 LayoutParams 를 원 하지 않 을 수도 있 습 니 다.XML 에서 지정 한 LayoutParams 는 무 시 됩 니 다.하위 View 가 부모 요 소 를 채 울 폭 을 지정 하 였 을 수도 있 지만,부모 View 는 wrap콘 텐 츠 로 인해 최종 View 가 많이 작 아 졌 습 니 다.
다음은 ViewGroup 이 루트 로 inflate()에 들 어 오 는 방법 이 없 는 경우 입 니 다.AlertDialog 에 사용자 정의 View 를 만 들 때 부모 요소 에 접근 할 수 없습니다.

AlertDialog.Builder dialogBuilder = new AlertDialog.Builder(mContext);
View customView = inflater.inflate(R.layout.custom_alert_dialog, null);
...
dialogBuilder.setView(customView);
dialogBuilder.show();
이 경우 null 을 루트 뷰 그룹 으로 전송 할 수 있 습 니 다.나중에 나 는 AlertDialog 가 LayoutParams 를 다시 쓰 고 각종 인 자 를 match 로 설정 하 는 것 을 발견 했다.parent。그러나 규칙 은 View Group 이 들 어 올 수 있 을 때 들 어 옵 니 다.
붕괴,이상 한 표현 과 오 해 를 피하 다.
이 글 이 Layout Inflater 를 사용 할 때 붕괴,이상 한 표현 과 오 해 를 피 하 는 데 도움 이 되 기 를 바 랍 니 다.다음은 문장의 요점 을 정리 했다.
4.567917.View Group 에 루트 요소 로 들 어 갈 수 있다 면 들 어 갑 니 다
  • null 을 루트 뷰 그룹 으로 전송 하 는 것 을 피한다
  • layot 파일 의 View 를 ViewGroup 에 추가 하 는 것 을 책임 지지 않 을 때 attachToRoot 인 자 를 false 로 설정 합 니 다
  • View 가 View Group 에 추가 되 었 을 때 true 에 들 어가 지 마 십시오
  • 사용자 정의 View 시 attachToRoot 를 true 로 설정 하기에 적합 합 니 다.
  • 읽 어 주 셔 서 감사합니다. 여러분 에 게 도움 이 되 기 를 바 랍 니 다.본 사이트 에 대한 여러분 의 지지 에 감 사 드 립 니 다!

    좋은 웹페이지 즐겨찾기